class DeliverablesController < ApplicationController
  layout "application"

  def index
    list
    render :action => 'list'
  end

  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
  verify :method => :post, :only => [ :destroy, :create, :update ],
         :redirect_to => { :action => :list }

  def list
    @deliverable_pages, @deliverables = paginate :deliverables, :per_page => 10
  end

  def show
    @deliverable = Deliverable.find(params[:id])
  end

  def new
    @deliverable = Deliverable.new
    @deliverable.schedulable_id = params[:schedulable_id]
    @deliverable.schedulable_type = params[:schedulable_type]
    @status_options = options_for_status
  end

  def create
    @deliverable = Deliverable.new(params[:deliverable])
    if @deliverable.save
      flash[:notice] = 'Deliverable was successfully created.'
      render_deliverable_owner(@deliverable)
    else
      @status_options = options_for_status
      render :action => 'new'
    end
  end

  def edit
    @deliverable = Deliverable.find(params[:id])
    @status_options = options_for_status
  end

  def update
    @status_options = options_for_status
    @deliverable = Deliverable.find(params[:id])

    if @deliverable.update_attributes(params[:deliverable])

      if @deliverable.status == 'Moved to next iteration'
        most_recent_iteration = Iteration.most_recent_iteration

        if @deliverable.schedulable_id != most_recent_iteration.id
          most_recent_iteration.clone_and_add_deliverable(@deliverable)
        end

      else if @deliverable.status == 'Deferred'

        #TODO translate this to a seperate method possibly in Todo model
        todo_list = params[:todo_list]
        if todo_list && (todo_list[:id].to_i != 0)
          todo_list = TodoList.find(todo_list[:id])
          cloned_deliverable = @deliverable.deep_clone
          cloned_deliverable.schedulable = todo_list
          cloned_deliverable.save
        end
      end

    end
    flash[:notice] = 'Deliverable was successfully updated.'
    render_deliverable_owner(@deliverable)
  else
    render :action => 'edit'
  end
end

def render_deliverable_owner(deliverable)
  if deliverable.schedulable_type == "Iteration"
    redirect_to :controller => :iterations,
    :action => :show, :id => deliverable.schedulable_id
  else
    redirect_to :controller => :todo_lists,
      :action => :show, :id => deliverable.schedulable_id
  end
end

def destroy
  deliverable = Deliverable.find(params[:id])
  if deliverable.destroy
    flash[:notice] = 'Deliverable was successfully deleted.'
  else
    flash[:notice] = 'Error deleting deliverable'
  end

  render_deliverable_owner(deliverable)
  end

  def options_for_status
    options = Deliverable.status_codes.collect do |code, value|
      [value, code]
    end

    options.sort { |a, b| a.first <=> b.first }
  end

  def auto_complete_for_deliverable_feature_name

    #get the deliverable and extract the feature name
    deliverable = Deliverable.new(params[:deliverable])
    feature_name = deliverable.feature_name.strip

    #search for matching features
    matching_features = Feature.name_starts_with(feature_name)
    
    #render list
    list_items = matching_features.collect do |feature|
      '<li>' + feature.name + '</li>'
    end
    render :text => '<ul>' + list_items.join + '</ul>'
  end

  def auto_complete_for_deliverable_project_name

    #get the deliverable and extract the project name
    deliverable = Deliverable.new(params[:deliverable])
    project_name = deliverable.project_name.strip

    #search for matching projects
    matching_projects = Project.name_starts_with(project_name)
    
    #render list
    list_items = matching_projects.collect do |project|
      '<li>' + project.name + '</li>'
    end
    render :text => '<ul>' + list_items.join + '</ul>'
  end

  def auto_complete_for_deliverable_product_name

    #get the deliverable and extract the product name
    deliverable = Deliverable.new(params[:deliverable])
    product_name = deliverable.product_name.strip

    #search for matching products
    matching_products = Product.name_starts_with(product_name)
    
    #render list
    list_items = matching_products.collect do |product|
      '<li>' + product.name + '</li>'
    end
    render :text => '<ul>' + list_items.join + '</ul>'
  end

  def auto_complete_for_deliverable_resource_names_csv

    # get the contents of the resources field
    deliverable = Deliverable.new(params[:deliverable])

    # collect the resource names
    resource_names = deliverable.resource_names

    # isolate the resource that is currently being entered
    search = resource_names.pop || ''

    # find a list of possible matches for the last resource
    matches = Resource.names

    # filter the matches by deleting the resources that were already typed in
    matches = matches - resource_names
    
    # filter the list of possible matches by the search string
    if not search.empty?
      matches = matches.delete_if do |resource_name|
        not resource_name.starts_with?(search)
      end
    end

    # return the auto complete list
    render_auto_complete(resource_names, matches)
  end

  def render_auto_complete(resource_names, matches)
    resource_names = resource_names.collect { |name| Resource.format_name(name) }
    matches = matches.collect { |match| Resource.format_name(match) }

    list_items = matches.collect do |match|
      '<li>' + (resource_names + [match]).join(', ') + '</li>'
    end

    render :text => '<ul>' + list_items.join + '</ul>'
  end

  def get_todo_lists

    #TODO Cleanup how the status is translated
    status_id = params[:deliverable_status_id].to_i
    status = Deliverable.status_codes

    if status[status_id] == 'Deferred'
      @todo_lists = TodoList.find(:all)
      render :partial => 'todo_lists'
    else
      render :text =>''
    end
  end
end
